// 高级类型

function advanced_eg01() {
  /**
 * Takes a string and adds "padding" to the left.
 * If 'padding' is a string, then 'padding' is appended to the left side.
 * If 'padding' is a number, then that number of spaces is added to the left side.
 */
  function padLeft(value: string, padding: string | number) {
    if (typeof padding === "number") {
      return Array(padding + 1).join(" ") + value;
    }
    if (typeof padding === "string") {
      return padding + value;
    }
    throw new Error(`Expected string or number, got '${padding}'.`);
  }

  let rees = padLeft("Hello world", 4); // returns "    Hello world"
  // padLeft("Hello world", true); // 运行的时候报错，使用联合类型 改 padding: string | number
  console.log(rees);
  // 联合类型表示一个值可以是几种类型之一。我们用竖线（ |）分隔每个类型。
}

function advanced_eg02() {
  interface Bird {
    fly(): void;
    layEggs(): void;
  }

  interface Fish {
    swim(): void;
    layEggs(): void;
  }

  function getSmallPet(): Fish | Bird {
    return { fly: function () { }, layEggs: function () { } }
  }

  let pet = getSmallPet();
  pet.layEggs(); // okay
  // pet.swim();    // errors
}

function advanced_eg03() {
  // Exclude<T, U> -- 从T中剔除可以赋值给U的类型。
  type T00 = Exclude<"a" | "b" | "c" | "d", "a" | "c" | "f">

  // Extract<T, U> -- 提取T中可以赋值给U的类型。
  type T01 = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">

  type T02 = Exclude<string | number | (() => void), Function>
  type T03 = Extract<string | number | (() => void), Function>

  // NonNullable<T> -- 从T中剔除null和undefined。
  type T04 = NonNullable<string | number | null | undefined>

  // ReturnType<T> -- 获取函数返回值类型。
  type T10 = ReturnType<() => string>;  // string

  // InstanceType<T> -- 获取构造函数类型的实例类型。
  // type T20 = InstanceType<typeof C>;  // C
  type T21 = InstanceType<any>;  // any
  type T22 = InstanceType<never>;  // any
  // type T23 = InstanceType<string>;  // Error
  // type T24 = InstanceType<Function>;  // Error
}

advanced_eg01();